package ar.edu.unlam.tpfinal.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import ar.edu.unlam.tpfinal.model.Address;
import ar.edu.unlam.tpfinal.persistence.dao.AddressDAO;
import ar.edu.unlam.tpfinal.persistence.exceptions.PersistenceExceptionWrapper;
import ar.edu.unlam.tpfinal.service.AddressService;
import ar.edu.unlam.tpfinal.service.exceptions.ServiceException;
import ar.edu.unlam.tpfinal.struts.forms.AddressForm;

@Service(value="addressService")
public class AddressServiceImpl implements AddressService {
	
	@Autowired
	private AddressDAO addressDAO;

	// DI con Spring
	public void setAddressDAO(AddressDAO addressDAO) {
		this.addressDAO = addressDAO;
	}

	@Override
	public void updateAddress(AddressForm addressForm) {
		try {
			Address address = addressDAO.findByOID(Long.parseLong(addressForm.getOid()));
			update(address, addressForm);
			addressDAO.save(address);
		} catch (PersistenceExceptionWrapper ex) {
			throw new ServiceException(ex);
		}
	}

	@Override
	public void insertAddress(AddressForm addressForm) {
		try {
			Address address = transform(addressForm);
			addressDAO.save(address);
		} catch (PersistenceExceptionWrapper ex) {
			throw new ServiceException(ex);
		}
	}

	@Override
	public void deleteAddress(AddressForm addressForm) {
		try {
			Address address = addressDAO.findByOID(Long.parseLong(addressForm.getOid()));
			addressDAO.delete(address);
		} catch (PersistenceExceptionWrapper ex) {
			throw new ServiceException(ex);
		}
	}

	@Override
	public AddressForm getAddress(Long oid) {
		try {
			Address address = addressDAO.findByOID(oid);
			AddressForm addressForm = transform(address);
			return addressForm;
		} catch (PersistenceExceptionWrapper ex) {
			throw new ServiceException(ex);
		}
	}

	@Override
	public List<AddressForm> getAllAddresses() {
		try {
			List<Address> listOfAddresses = addressDAO.findAll();
			List<AddressForm> listOfAddressForms = new ArrayList<AddressForm>();
			for(Address address : listOfAddresses)
				listOfAddressForms.add(transform(address));
			return listOfAddressForms;
		} catch (PersistenceExceptionWrapper ex) {
			throw new ServiceException(ex);
		}
	}
	
	@Override
	public Long findAddressOid(AddressForm addressForm) throws ServiceException {
		try {
			Address address = transform(addressForm);
			Address foundAddress = 
					addressDAO.getUniqueObjectByProperties(
									new String[] {"street", "city", "state", "country", "zipcode"},
									new Object[] {address.getStreet(), address.getCity(), address.getState(), address.getCountry(), address.getZipcode()}
									);		
			return foundAddress.getOid();
		} catch (PersistenceExceptionWrapper ex) {
			throw new ServiceException(ex);
		}
	}
	
	private Address transform(AddressForm addressForm) {
		Address address = new Address();
		
		address.setStreet(addressForm.getStreet());
		address.setCity(addressForm.getCity());
		address.setState(addressForm.getState());
		address.setCountry(addressForm.getCountry());
		address.setZipcode(addressForm.getZipcode());
		
		return address;
	}
	
	private AddressForm transform(Address address) {
		AddressForm addressForm = new AddressForm();
		
		addressForm.setOid(address.getOid().toString());
		addressForm.setStreet(address.getStreet());
		addressForm.setCity(address.getCity());
		addressForm.setState(address.getState());
		addressForm.setCountry(address.getCountry());
		addressForm.setZipcode(address.getZipcode());
		
		return addressForm;
	}
	
	private void update(Address address, AddressForm addressForm) {
		address.setStreet(addressForm.getStreet());
		address.setCity(addressForm.getCity());
		address.setState(addressForm.getState());
		address.setCountry(addressForm.getCountry());
		address.setZipcode(addressForm.getZipcode());
	}

}
